package awl;

import static robocode.util.Utils.normalRelativeAngleDegrees;
import java.awt.Color;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import robocode.HitWallEvent;
import robocode.HitRobotEvent;
import robocode.RobotDeathEvent; 
import robocode.HitByBulletEvent;

/**
 * Traverses in rectangular pattern forever to avoid much damage as possible.
 * Ram the opponent if close or move in different direction when fired on.
 * @author Alan Lee
 *
 */
public class Xinetd extends Robot {
  String enemy = null; //No enemy detected.
  double degree = 10; //Turn angle of gun turret
  
  /**
   * Move in rectangular counter-clockwise pattern to avoid certain robots like Corners Robot.
   */
  public void run() {
    setBodyColor(Color.BLACK);
    setGunColor(Color.YELLOW);
    setRadarColor(Color.red);
    
    //Face North.
    turnLeft(getHeading() % 360);
    ahead(getBattleFieldHeight() - 400);
    turnRight(90);
    ahead(getBattleFieldWidth() - 600);
    turnRight(90);
    //Continue avoiding much possible damage by moving in a smaller rectangular pattern.
    while ((getOthers()) != 1) {
      ahead((getBattleFieldHeight() - 400) * 1.75);
      turnRight(90);
      ahead((getBattleFieldWidth() - 600) * 1.75);
      turnRight(90);
    }
    turnRight(getHeading() % 360);
    ahead(getBattleFieldHeight());
    //Gun is always pointing inside.
    turnGunLeft(90);
    //Move like the Walls robot parallel around the wall.
    while ((getOthers()) == 1) {
      ahead(getBattleFieldHeight());
      ahead(getBattleFieldWidth());
    }
  }
  
  /**
   * Find our first target when radar sees enemies and gun tries to destroy it.
   * @param badguy - information about the enemy can be used by our robot.
   */
  public void onScannedRobot(ScannedRobotEvent badguy) {
    String detectedOne;
    double oldBearing;
    oldBearing = badguy.getBearing();
    if (enemy == null) {
      enemy = badguy.getName();  //Found our first enemy.
      fire(3);
    }
    else {
      detectedOne = badguy.getName();
      //Check to see if this enemy has been the one we wanted.
      if (detectedOne.equals(enemy)) {
        if (oldBearing > 0) {
          //Gun points at target when close range
          oldBearing = badguy.getBearing();
          degree = normalRelativeAngleDegrees(oldBearing + (getHeading() - getRadarHeading()));
          turnGunRight(degree);
          fire(2);
        }
        else {
          //Look more left for target
          turnGunRight(-(badguy.getBearing()));
          fire(2); 
        } //end else
      } //end if*/
    } //end else
  }
  
  /**
   * Ram that enemy blocking our path.
   * @param robot - information about the target which our robot can use.
   */
  public void onHitRobot(HitRobotEvent robot) {
    double degree;
    degree = normalRelativeAngleDegrees(robot.getBearing() + (getHeading() - getRadarHeading()));
    //Point at enemy close range.
    turnGunRight(degree);
    ahead(100);
    fire(3);
  }
  
  /**
   * When robot hit the wall move counter-clockwise.
   * @param robot - information about enemy which our robot can use.
   */
  public void onHitWall(HitWallEvent robot) {
    turnLeft(90);
    ahead(change(90));
  }
  
  /**
   * Find next target if our target is destroyed.
   * @param robot - information about enemy which our robot can use.
   */
  public void onRobotDeath(RobotDeathEvent robot) {
    enemy = null; //Reset since no enemy.
    scan();
  }
  
  /**
   * When enemy's bullet hit, it attempts to dodge under fire.
   * @param robot - information about enemy for our robot to use.
   */
  public void onHitByBullet(HitByBulletEvent robot) {
    degree = normalRelativeAngleDegrees(robot.getBearing() + (getHeading() - getRadarHeading()));
    turnGunRight(degree);
    turnLeft(45);
    ahead(20);    
  }
  
  /**
   * During battle, robot may hit wall so turn if necessary.
   * @param deg - amount of degree change.
   * @return deg - amount increased by ten.
   */
  public double change(double deg) {
    double move = 0.0; //number pixel move
    move = deg + 10;
    return move;
  }
}
